package indi.zjh.dp.db;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.dom4j.DocumentException;

import indi.zjh.dp.orm.Business;
import indi.zjh.dp.orm.BusinessMapDataStrategy;
import indi.zjh.dp.orm.RelationClass;

public class Table {
	public static final int INNODB = 0;
	public static final int MYISAM = 1;
	protected String tableName;
	protected List<TField> fields;
	protected int engine;
	// 是否忽略已存在检查
	protected boolean ignore = false;
	public boolean isIgnore() {
		return ignore;
	}

	public void setIgnore(boolean ignore) {
		this.ignore = ignore;
	}

	//protected RelationClass relationClass;
	public Table(String tableName)
	{
		//this.relationClass = rc;
		this.tableName = tableName;
		this.engine = INNODB;
		this.fields = new ArrayList<TField>();
	}
	
	public String getName()
	{
		return this.tableName;
	}
	
	public void addField(TField f)
	{
		boolean isExist = false;
		
		Iterator<TField> iter = this.fields.iterator();
		while(iter.hasNext())
		{
			TField tf = iter.next();
			if(tf.name.equals(f.name))
			{
				isExist = true;
				break;
			}
		}
		
		if(!isExist)
			this.fields.add(f);	
	}
	
	public void addField(List<TField> flds)
	{
		Iterator<TField> iter = flds.iterator();
		while(iter.hasNext())
		{
			this.addField(iter.next());
		}
	}
	
	/**
	 * 对表的字段名称进行排序
	 */
	public void sortFields()
	{
		Collections.sort(this.fields, new Comparator<TField>() {
			@Override
			public int compare(TField o1, TField o2) {
				// TODO Auto-generated method stub
				return o1.name.compareTo(o2.name);
			}
		});
	}
	
	public void setEngine(int engine) throws Exception
	{
		if(engine != INNODB && engine != MYISAM)
			throw new Exception("不支持的数据库引擎");
		this.engine = engine;
	}
	
	public String getDropSql()
	{
		return "DROP TABLE IF EXISTS `" + this.tableName + "`";
	}
	
	public String getClearSql()
	{
		return "DELETE FROM `" + this.tableName + "`";
	}
	
	public String getSelectSql()
	{
		StringBuffer sb = new StringBuffer();
		String[] fieldstr = new String[this.fields.size()];
		Iterator<TField> iter = this.fields.iterator();
		int i = 0;
		while(iter.hasNext())
		{
			fieldstr[i++] = "`"+iter.next().name+"`";
		}
		sb.append("SELECT ");
		sb.append(String.join(",", fieldstr));
		sb.append(" FROM ");
		sb.append(this.tableName);
		sb.append(" WHERE `_id` = ? and `_deleted` = 0");
		
		return sb.toString();
	}
	
	public String getUpdateSql()
	{
		StringBuffer sb = new StringBuffer();
		
		String[] strfield = new String[this.fields.size()];
		Iterator<TField> iter = this.fields.iterator();
		int i = 0;
		while(iter.hasNext())
		{
			strfield[i++] = "\t`" + iter.next().name + "` = ?";
		}
		sb.append("UPDATE ");
		sb.append(this.tableName);
		sb.append(" SET ");
		sb.append("\n");
		sb.append(String.join(",\n", strfield));
		sb.append(" WHERE `_id` = ? AND `_v` = ?");

		return sb.toString();
	}
	
	public String getInsertSql()
	{
		StringBuffer sb = new StringBuffer();
		
		String tableName = this.tableName;

		sb.append("INSERT INTO `" + tableName + "`");
		
		Iterator<TField> iter = this.fields.iterator();
		
		String[] strfields = new String[this.fields.size()];
		String[] values = new String[this.fields.size()];
		int i = 0;
		while(iter.hasNext())
		{
			TField tf = iter.next();
			strfields[i] = "\t`" + tf.name + "`";
			values[i] = "?";
			++i;
		}
		sb.append("(\n" + String.join(",\n", strfields) + ")");
		sb.append("VALUES(" + String.join(",", values) + "\n)");
		return sb.toString();
	}

	
	public String getCreateSql()
	{
		this.sortFields();
		StringBuffer sb = new StringBuffer();
		Iterator<TField> iter = this.fields.iterator();
		int len = this.fields.size();
		int pos = 0;
		
		TField primaryField = null;
		while(iter.hasNext())
		{
			TField field = iter.next();
			if(field.isPrimary)
				primaryField = field;
			sb.append("\t");
			sb.append(field.getString());
			if(pos < len - 1)
				sb.append(",\n");
			++pos;
		}
		if(primaryField == null)
		{
			return "";
		}
		
		if(this.ignore)
			sb.insert(0, "CREATE TABLE IF NOT EXISTS `" + this.tableName + "`(\n");
		else
			sb.insert(0, "CREATE TABLE `" + this.tableName + "`(\n");
		
		if(Configuration.isMysql())
			sb.append(", PRIMARY KEY(`" + primaryField.name + "`)");
		
		sb.append(")");
		
		
		if(Configuration.isMysql())
		{	
			if(this.engine == INNODB)
			{
				sb.append("ENGINE=InnoDB");
			}
			else 
			{
				sb.append("ENGINE=MyISAM");
			}
			sb.append(" DEFAULT CHARSET=UTF8");
		}
		return sb.toString();
	}
	
}
